#ifndef __deadz80_h__
#define __deadz80_h__

#include "../CPU.h"

#define BAD_OPCODE		0x80000000

#define Z80_PAGE_SHIFT	12
#define Z80_PAGE_MASK	0x0FFF
#define Z80_PAGE_NUM	0x10

#define Z80_NMI			-1
#define Z80_IRQ			-2
#define Z80_IGNORE_IRQ	-3

typedef struct sz80Regs {
	union {
		struct {unsigned char f,a;} byte;
		unsigned short word;
	} af;
	union {
		struct {unsigned char c,b;} byte;
		unsigned short word;
	} bc;
	union {
		struct {unsigned char e,d;} byte;
		unsigned short word;
	} de;
	union {
		struct {unsigned char l,h;} byte;
		unsigned short word;
	} hl;
} z80Regs;

class CDeadZ80:public CCPU
	{
	protected:
		//cpu registers
		z80Regs main,alt;		//user register sets
		z80Regs *regs;			//current selected register set
		unsigned short pc;		//program counter
		unsigned short sp;		//stack pointer
		unsigned short ix,iy;	//index registers
		unsigned char ip;		//interrupt page register
		unsigned char mr;		//memory refresh register
		unsigned char iff1,iff2;
	
		unsigned long cycles;	//cycle counter
		unsigned char halt;		//cpu halt state
		unsigned long opcode;
		unsigned char intmode;
		unsigned char intenable;
		unsigned char inside_irq;
		unsigned char *readpages[Z80_PAGE_NUM];
		unsigned char *writepages[Z80_PAGE_NUM];
	//	unsigned char (*readfunc)(unsigned long);
	//	void (*writefunc)(unsigned long,unsigned char);
		ReadFunc *readfunc;
		WriteFunc *writefunc;
		IRQFunc *irqfunc;
		void *user;

	public:
		CDeadZ80();
		~CDeadZ80();
		void Init();
		void Reset();
		void NMI();
		void IRQ();
		u32 Execute(u32 c);
		int ExecuteOpcodeDDCB();
		int ExecuteOpcodeCB();
		int ExecuteOpcodeDD();
		int ExecuteOpcodeED();
		int ExecuteOpcodeFD();
		int Step();
		unsigned char ReadMemory8(unsigned long addr);
		unsigned short ReadMemory16(unsigned long addr);
		void WriteMemory8(unsigned long addr,unsigned char data);
		void WriteMemory16(unsigned long addr,unsigned short data);
		u32 Disassemble(char *dest,u32 p);
		char *GenerateRegNames(char *dest);
		char *GenerateRegData(char *dest);
		u32 GetPC();
		u32 GetCycle();
		virtual void SetRead(ReadFunc *r);
		virtual void SetWrite(WriteFunc *w);
		virtual void SetIRQ(IRQFunc *i);
		virtual void SetUser(void *u);
		virtual void SetReadPage(int p,u8 *d);
		virtual void SetWritePage(int p,u8 *d);
		virtual void SetPage(int p,u8 *d);
	};
#endif
